import { app, shell, BrowserWindow, ipcMain, screen } from 'electron'
import { join } from 'path'
import { electronApp, optimizer, is } from '@electron-toolkit/utils'
import icon from '../../resources/icon.png?asset'

const windows: BrowserWindow[] = []
const windowPositions: Array<{ x: number; y: number; width: number; height: number }> = []

const WINDOW_WIDTH = 260
const WINDOW_HEIGHT = 140
const WINDOW_SPACING = 15
const WINDOW_COUNT = 100 
const POPUP_DELAY = 250 

const colorThemes = [
  '#FF6B9D', '#C44569', '#F8B500', '#FF9F43', '#EE5A6F',
  '#F0932B', '#EB4D4B', '#6C5CE7', '#A29BFE', '#00D2D3',
  '#00D2FF', '#55EFC4', '#74B9FF', '#0984E3', '#A8E6CF',
  '#FFD93D', '#FDCB6E', '#E17055', '#D63031', '#2D3436'
]

function isOverlapping(x: number, y: number, width: number, height: number): boolean {
  for (const pos of windowPositions) {
    const spacing = WINDOW_SPACING
    if (
      x < pos.x + pos.width + spacing &&
      x + width + spacing > pos.x &&
      y < pos.y + pos.height + spacing &&
      y + height + spacing > pos.y
    ) {
      return true
    }
  }
  return false
}

function getRandomPosition(): { x: number; y: number } {
  const { width: screenWidth, height: screenHeight } = screen.getPrimaryDisplay().workAreaSize
  
  const maxAttempts = 3000 
  
  for (let attempt = 0; attempt < maxAttempts; attempt++) {
    const x = Math.floor(Math.random() * Math.max(1, screenWidth - WINDOW_WIDTH))
    const y = Math.floor(Math.random() * Math.max(1, screenHeight - WINDOW_HEIGHT))
    
    if (!isOverlapping(x, y, WINDOW_WIDTH, WINDOW_HEIGHT)) {
      return { x, y }
    }
  }
  
  const numRegions = Math.ceil(Math.sqrt(windowPositions.length + 1)) || 5
  const regionCols = Math.ceil(Math.sqrt(numRegions))
  const regionRows = Math.ceil(numRegions / regionCols)
  const regionWidth = screenWidth / regionCols
  const regionHeight = screenHeight / regionRows
  
  const randomRegion = Math.floor(Math.random() * numRegions)
  const regionCol = randomRegion % regionCols
  const regionRow = Math.floor(randomRegion / regionCols)
  
  for (let attempt = 0; attempt < 1000; attempt++) {
    const regionStartX = regionCol * regionWidth
    const regionStartY = regionRow * regionHeight
    const x = Math.floor(regionStartX + Math.random() * Math.max(0, regionWidth - WINDOW_WIDTH))
    const y = Math.floor(regionStartY + Math.random() * Math.max(0, regionHeight - WINDOW_HEIGHT))
    
    const finalX = Math.max(0, Math.min(x, screenWidth - WINDOW_WIDTH))
    const finalY = Math.max(0, Math.min(y, screenHeight - WINDOW_HEIGHT))
    
    if (!isOverlapping(finalX, finalY, WINDOW_WIDTH, WINDOW_HEIGHT)) {
      return { x: finalX, y: finalY }
    }
  }
  
  const centerX = Math.random() * screenWidth
  const centerY = Math.random() * screenHeight
  const radiusX = screenWidth * 0.4
  const radiusY = screenHeight * 0.4
  
  for (let attempt = 0; attempt < 1000; attempt++) {
    const angle = Math.random() * Math.PI * 2
    const distance = Math.random()
    const x = Math.floor(centerX + Math.cos(angle) * radiusX * distance - WINDOW_WIDTH / 2)
    const y = Math.floor(centerY + Math.sin(angle) * radiusY * distance - WINDOW_HEIGHT / 2)
    
    const finalX = Math.max(0, Math.min(x, screenWidth - WINDOW_WIDTH))
    const finalY = Math.max(0, Math.min(y, screenHeight - WINDOW_HEIGHT))
    
    if (!isOverlapping(finalX, finalY, WINDOW_WIDTH, WINDOW_HEIGHT)) {
      return { x: finalX, y: finalY }
    }
  }
  
  return {
    x: Math.floor(Math.random() * Math.max(1, screenWidth - WINDOW_WIDTH)),
    y: Math.floor(Math.random() * Math.max(1, screenHeight - WINDOW_HEIGHT))
  }
}

// 存储每个窗口的配置
const windowConfigsMap = new Map<number, { messageIndex: number; colorIndex: number }>()
let windowIdCounter = 0

function createWindow(messageIndex: number, colorIndex: number): void {
  const position = getRandomPosition()
  const { x, y } = position
  
  windowPositions.push({ x, y, width: WINDOW_WIDTH, height: WINDOW_HEIGHT })
  
  const windowId = windowIdCounter++
  windowConfigsMap.set(windowId, { messageIndex, colorIndex })
  
  const window = new BrowserWindow({
    width: WINDOW_WIDTH,
    height: WINDOW_HEIGHT,
    x,
    y,
    show: false,
    frame: false,
    transparent: true,
    alwaysOnTop: true,
    skipTaskbar: false,
    resizable: false,
    autoHideMenuBar: true,
    ...(process.platform === 'linux' ? { icon } : {}),
    webPreferences: {
      preload: join(__dirname, '../preload/index.js'),
      sandbox: false
    }
  })

  windows.push(window)

  // 在窗口加载完成后发送配置数据
  window.webContents.once('did-finish-load', () => {
    const config = windowConfigsMap.get(windowId)
    if (config) {
      window.webContents.send('window-config', config)
    }
  })

  window.on('ready-to-show', () => {
    window.show()
  })

  window.webContents.setWindowOpenHandler((details) => {
    shell.openExternal(details.url)
    return { action: 'deny' }
  })

  // 不再使用 URL 参数，直接加载页面
  if (is.dev && process.env['ELECTRON_RENDERER_URL']) {
    window.loadURL(process.env['ELECTRON_RENDERER_URL'])
  } else {
    window.loadFile(join(__dirname, '../renderer/index.html'))
  }
  
  // 窗口关闭时清理配置
  window.on('closed', () => {
    windowConfigsMap.delete(windowId)
  })
}

function createAllWindows(): void {
  windowPositions.length = 0
  windows.length = 0
  windowConfigsMap.clear()
  windowIdCounter = 0
  
  const colorIndices = Array.from({ length: colorThemes.length }, (_, i) => i)
  
  const shuffle = <T>(array: T[]): T[] => {
    const newArray = [...array]
    for (let i = newArray.length - 1; i > 0; i--) {
      const j = Math.floor(Math.random() * (i + 1));
      [newArray[i], newArray[j]] = [newArray[j], newArray[i]]
    }
    return newArray
  }
  
  const shuffledColors = shuffle(colorIndices)

  // 预先生成所有窗口的消息和颜色索引，确保每个都不同
  const messageIndices = Array.from({ length: 30 }, (_, i) => i)
  const shuffledMessages = shuffle([...messageIndices])
  
  const windowConfigs: Array<{ messageIndex: number; colorIndex: number }> = []
  
  // 为每个窗口生成唯一的消息和颜色组合
  for (let i = 0; i < WINDOW_COUNT; i++) {
    // 消息：循环使用打乱后的消息数组，确保分布均匀
    const messageIndex = shuffledMessages[i % shuffledMessages.length]
    
    // 颜色：使用打乱后的颜色，并添加基于索引的偏移，确保多样性
    // 使用 i * 7 这样的质数偏移，确保颜色分布更均匀
    const colorIndex = shuffledColors[(i * 7) % shuffledColors.length]
    
    windowConfigs.push({
      messageIndex,
      colorIndex
    })
  }
  
  // 再次完全打乱窗口配置顺序，增加随机性
  const finalConfigs = shuffle(windowConfigs)

  // 依次创建窗口
  for (let i = 0; i < WINDOW_COUNT; i++) {
    setTimeout(() => {
      const config = finalConfigs[i]
      // 调试信息
      if (i < 5 || i % 20 === 0) {
        console.log(`创建窗口 ${i}: 消息索引=${config.messageIndex}, 颜色索引=${config.colorIndex}`)
      }
      createWindow(config.messageIndex, config.colorIndex)
    }, i * POPUP_DELAY)
  }
}

// This method will be called when Electron has finished
// initialization and is ready to create browser windows.
// Some APIs can only be used after this event occurs.
app.whenReady().then(() => {
  // Set app user model id for windows
  electronApp.setAppUserModelId('com.electron')

  // Default open or close DevTools by F12 in development
  // and ignore CommandOrControl + R in production.
  // see https://github.com/alex8088/electron-toolkit/tree/master/packages/utils
  app.on('browser-window-created', (_, window) => {
    optimizer.watchWindowShortcuts(window)
  })

  // IPC handlers
  ipcMain.on('ping', () => console.log('pong'))
  
  // 处理窗口配置请求
  ipcMain.handle('get-window-config', (event) => {
    // 找到对应的窗口
    const targetWindow = BrowserWindow.fromWebContents(event.sender)
    if (!targetWindow) {
      return { messageIndex: 0, colorIndex: 0 }
    }
    
    // 通过窗口实例查找配置
    for (const [id, config] of windowConfigsMap.entries()) {
      if (windows[id] === targetWindow) {
        return config
      }
    }
    
    // 如果找不到，返回默认值
    return { messageIndex: 0, colorIndex: 0 }
  })

  // 创建所有窗口
  createAllWindows()

  app.on('activate', function () {
    // On macOS it's common to re-create a window in the app when the
    // dock icon is clicked and there are no other windows open.
    if (BrowserWindow.getAllWindows().length === 0) createAllWindows()
  })
})

// Quit when all windows are closed, except on macOS. There, it's common
// for applications and their menu bar to stay active until the user quits
// explicitly with Cmd + Q.
app.on('window-all-closed', () => {
  if (process.platform !== 'darwin') {
    app.quit()
  }
})

// In this file you can include the rest of your app's specific main process
// code. You can also put them in separate files and require them here.
